package czk.concrent.threadpool.forkandjoin.practice;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * @Author:ChenZhangKun
 * @Date: 2021/9/30 14:46
 */
public class ForkAndJoinPractice2 {
    public static void main(String[] args) {
        // System.out.println(test());
        testFork();
    }

    public static Long test() {
        System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ssSS")));
        long sum = 0;
        for (int i = 0; i <= 1000000; i++) {
            sum += i;

        }
        System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ssSS")));
        return sum;
    }

    public static void testFork() {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        SubForkAndJoin subForkAndJoin = new SubForkAndJoin(0, 10 * 100000);
        System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ssSS")));
        Long invoke = forkJoinPool.invoke(subForkAndJoin);
        System.out.println(invoke);
        System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ssSS")));
    }
}

class SubForkAndJoin extends RecursiveTask<Long> {
    // 开始
    private int start;
    // 结束
    private int end;
    // 阈值
    private static final int THRESH_HOLD = 500000;

    public SubForkAndJoin(int start, int end) {
        this.start = start;
        this.end = end;

    }

    @Override
    protected Long compute() {
        // 拿到中间值
        int len = end - start;
        if (len > THRESH_HOLD) {
            // 拿到中间值
            int middle = (end + start) / 2;
            // 左边
            System.out.println("拆分左边" + start + "到" + middle);
            // 左边
            SubForkAndJoin left = new SubForkAndJoin(start, middle);
            // 继续执行
            left.fork();
            // 右边
            System.out.println("拆分右边" + (middle + 1) + "到" + end);
            SubForkAndJoin right = new SubForkAndJoin(middle + 1, end);
            // 执行
            right.fork();
            // 汇总
            return left.join() + right.join();
        } else {
            // 计算值
            long sum = 0;
            for (int i = start; i <= end; i++) {
                sum += i;
            }
            System.out.println("计算结果=" + sum);
            return sum;
        }
    }
}

